home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / workbench / directoryopus4 / dopus4_src / library / dopus_stuff.c < prev    next >
C/C++ Source or Header  |  2000-03-11  |  44KB  |  1,260 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopuslib.h"
  32. //#include "config.h"
  33. //#include "configflags.h"
  34.  
  35. char *getstringcopy(char *);
  36. int readline(char *,int,char *,int);
  37. void DoAssignDrive(struct ConfigStuff *,int,char *,char *);
  38. void linkinnewfiletype(struct ConfigStuff *,struct dopusfiletype *);
  39. int writestring(int,char *);
  40. void freestring(char *);
  41.  
  42. void __stdargs _XCEXIT(long lcode) { }
  43.  
  44. __saveds DoReadConfig(register char *name __asm("a0"),
  45.     register struct ConfigStuff *cstuff __asm("a1"))
  46. {
  47.     int a,in,size,pos,b,bk,gad,mv;
  48.     USHORT ver,mag;
  49.     char *cbuf,*buf,*tbuf,buf2[102],buf3[102];
  50.     struct dopusfiletype *newtype;
  51.     struct olddopusfiletype otype;
  52.     struct dopusgadgetbanks *bank=NULL,*temp;
  53.     struct Config *config;
  54.     struct DOpusRemember *key;
  55.     struct dopusfunction *tempfunc;
  56.     struct dopusdrive *driveptr;
  57.     struct dopushotkey *hotkey,*curhotkey=NULL;
  58.  
  59.     if (!(config=cstuff->config)) return(-1);
  60.  
  61.     DoFreeConfig(cstuff);
  62.     if (DoCheckExist(name,&size)>=0) return(ERROR_OBJECT_NOT_FOUND);
  63.     size-=sizeof(struct Config);
  64.     if (!(in=Open(name,MODE_OLDFILE))) return(IoErr());
  65.     if ((Read(in,(char *)&ver,2))<2 || (Read(in,(char *)&mag,2))<2 ||
  66.         mag!=CONFIG_MAGIC || ver==0xde) {
  67.         if (mag==CONFIG_MAGIC && ver==0xde) {
  68.             struct DOpusSimpleRequest req;
  69.             char *gads[2];
  70.             int rets[1];
  71.  
  72.             req.text="Pre-3.32 configuration files not recognised!";
  73.             gads[0]="Continue"; gads[1]=NULL;
  74.             rets[0]=0;
  75.             req.gads=gads;
  76.             req.rets=rets;
  77.             req.hi=-1; req.lo=-1;
  78.             req.fg=-1; req.bg=-1;
  79.             req.strbuf=NULL;
  80.             req.flags=SRF_BORDERS;
  81.             req.font=GfxBase->DefaultFont;
  82.             req.title="Request";
  83.  
  84.             DoSimpleRequest(NULL,&req);
  85.         }
  86.         Close(in);
  87.         return(ERROR_NOT_CONFIG);
  88.     }
  89.     Seek(in,0,OFFSET_BEGINNING);
  90.     if ((Read(in,(char *)config,sizeof(struct Config)))<sizeof(struct Config)) {
  91.         Close(in);
  92.         return(IoErr());
  93.     }
  94.  
  95.     if (config->version<CONFIG_CHANGE_DISPLAY) {
  96.         for (a=0;a<2;a++) {
  97.             for (b=0;b<8;b++) {
  98.                 config->displaypos[a][b]=config->old_displaypos[a][b];
  99.                 config->displaylength[a][b]=config->old_displaylength[a][b];
  100.                 config->old_displaypos[a][b]=0;
  101.                 config->old_displaylength[a][b]=0;
  102.             }
  103.             for (b=8;b<16;b++) {
  104.                 config->displaypos[a][b]=-1;
  105.                 config->displaylength[a][b]=0;
  106.             }
  107.         }
  108.     }
  109.  
  110.     if (config->version<CONFIG_CHANGE_CONFIGXY) {
  111.         config->config_x=-1;
  112.         config->config_y=-1;
  113.     }
  114.  
  115.     if (config->version<CONFIG_CHANGE_DIMENS) {
  116.         config->scr_winx=config->wbwinx;
  117.         config->scr_winy=config->wbwiny;
  118.         config->scr_winw=config->scrw;
  119.         config->scr_winh=config->scrh;
  120.         config->pubscreen_name[0]=0;
  121.     }
  122.  
  123.     if (config->version<CONFIG_NEW_SLIDERS) {
  124.         config->slider_pos=1;
  125.     }
  126.  
  127.     if (config->version<=OLD_CONFIG_VERSION) {
  128.         config->scrdepth+=2;
  129.         config->dateformat=1;
  130.         for (a=0;a<2;a++) {
  131.             for (b=0;b<5;b++) config->displaypos[a][b]=b;
  132.             for (b=5;b<16;b++) config->displaypos[a][b]=-1;
  133.             config->displaylength[a][0]=28;
  134.             config->displaylength[a][1]=80;
  135.             config->displaylength[a][2]=40;
  136.             config->displaylength[a][3]=32;
  137.             config->displaylength[a][4]=32;
  138.             config->sortmethod[a]=0;
  139.             config->separatemethod[a]=1;
  140.         }
  141.         config->sortflags=0;
  142.         config->scrclktype=SCRCLOCK_MEMORY|SCRCLOCK_DATE|SCRCLOCK_TIME;
  143.         if (config->icontype==3) config->icontype=ICON_NOWINDOW;
  144.         else config->icontype=0;
  145.         config->icontype|=ICON_MEMORY|ICON_DATE|ICON_TIME;
  146.         config->showfree=1<<config->showfree;
  147.         config->hotkeyqual=config->hotkeycode&0xff;
  148.         config->hotkeycode>>=8;
  149.         config->stringfgcol=1; config->stringbgcol=0;
  150.         config->stringselfgcol=1; config->stringselbgcol=0;
  151.     }
  152.     if (config->version<=CONFIG_CHANGE_PALETTE) {
  153.         for (a=0,b=0;a<16;a++) {
  154.             config->new_palette[b++]=(((config->Palette[a]>>8)&0xf)<<28)|0x0fffffff;
  155.             config->new_palette[b++]=(((config->Palette[a]>>4)&0xf)<<28)|0x0fffffff;
  156.             config->new_palette[b++]=((config->Palette[a]&0xf)<<28)|0x0fffffff;
  157.         }
  158.     }
  159.     if (config->version<=CONFIG_CHANGE_BUFCOUNT) {
  160.         config->bufcount/=2;
  161.         if (config->bufcount<1) config->bufcount=1;
  162.     }
  163.     if (config->version<CONFIG_LESS_DODRIVES) {
  164.         if (!(tempfunc=AllocMem(sizeof(struct dopusfunction)*DRIVECOUNT,MEMF_CLEAR))) {
  165.             Close(in);
  166.             return(ERROR_NO_FREE_STORE);
  167.         }
  168.         driveptr=(struct dopusdrive *)config->drive;
  169.         for (a=0;a<OLDDRIVECOUNT;a++) {
  170.             strcpy(tempfunc[a].name,driveptr[a].name);
  171.             tempfunc[a].key=driveptr[a].key;
  172.             tempfunc[a].qual=driveptr[a].qual;
  173.             tempfunc[a].fpen=driveptr[a].fpen;
  174.             tempfunc[a].bpen=driveptr[a].bpen;
  175.             tempfunc[a].function=getstringcopy(driveptr[a].path);
  176.         }
  177.         for (a=OLDDRIVECOUNT;a<DRIVECOUNT;a++) tempfunc[a].fpen=3;
  178.         CopyMem((char *)tempfunc,(char *)driveptr,sizeof(struct dopusfunction)*DRIVECOUNT);
  179.         FreeMem(tempfunc,sizeof(struct dopusfunction)*DRIVECOUNT);
  180.     }
  181.     if (config->version<=CONFIG_CHANGE_DOSREQ) {
  182.         config->errorflags^=1;
  183.         config->hotkeyflags=0;
  184.         config->pad3=config->pad4=config->pad8=0;
  185.         for (a=0;a<2;a++) config->pad5[a]=config->pad7[a]=0;
  186.         for (a=0;a<232;a++) config->morepadding[a]=0;
  187.         for (a=0;a<2;a++) {
  188.             config->scrollborders[a].MinX=~0;
  189.             config->scrollborders[a].MaxX=~0;
  190.             config->scrollborders[a].MinY=~0;
  191.             config->scrollborders[a].MaxY=~0;
  192.         }
  193.         config->generalscreenflags=2;
  194.     }
  195.     if (config->version<=CONFIG_NEW_FUNCTIONS) {
  196.         for (a=0;a<MENUCOUNT;a++) {
  197.             strcpy(buf2,(char *)&config->menu[a]);
  198.             config->menu[a].name=getstringcopy(buf2);
  199.             config->menu[a].pad2[0]=0;
  200.             config->menu[a].pad2[1]=0;
  201.             config->menu[a].pad2[2]=0;
  202.         }
  203.     }
  204.     if (config->version<=CONFIG_CHANGE_ARROWS)
  205.         for (a=0;a<3;a++) config->arrowsize[a]=8;
  206.     if (config->version<=CONFIG_CHANGE_EXTERN) {
  207.         for (a=0;a<80;a++) config->pad5a[a]=config->configreturnscript[a]=0;
  208.         for (a=0;a<397;a++) config->pad9a[a]=0;
  209.         config->loadexternal=0;
  210.     }
  211.  
  212.     key=NULL;
  213.     if (!(cbuf=(char *)LAllocRemember(&key,size,MEMF_CLEAR)) ||
  214.         !(buf=(char *)LAllocRemember(&key,4096,MEMF_CLEAR)) ||
  215.         !(tbuf=(char *)LAllocRemember(&key,256,MEMF_CLEAR))) {
  216.         Close(in);
  217.         LFreeRemember(&key); 
  218.         return(ERROR_NO_FREE_STORE);
  219.     }
  220.     Read(in,cbuf,size);
  221.     Close(in);
  222.  
  223.     for (a=0;a<MENUCOUNT;a++) {
  224.         config->menu[a].function=NULL;
  225.         if (config->version>CONFIG_NEW_FUNCTIONS) config->menu[a].name=NULL;
  226.     }
  227.     if (config->version>OLD_CONFIG_VERSION) {
  228.         for (a=0;a<DRIVECOUNT;a++) config->drive[a].function=NULL;
  229.     }
  230.  
  231.     pos=0;
  232.     for (a=0;a<MENUCOUNT;a++) {
  233.         pos=readline(cbuf,pos,buf,size);
  234.         if (buf[0]) DoAssignMenu(cstuff,a,(char *)-1,buf);
  235.         if (pos==-1) goto endthis;
  236.     }
  237.     if (config->version>CONFIG_NEW_FUNCTIONS) {
  238.         for (a=0;a<MENUCOUNT;a++) {
  239.             pos=readline(cbuf,pos,buf,size);
  240.             if (buf[0]) DoAssignMenu(cstuff,a,buf,(char *)-1);
  241.             if (pos==-1) goto endthis;
  242.         }
  243.     }
  244.  
  245.     if (config->version>OLD_CONFIG_VERSION) {
  246.         for (a=0;a<DRIVECOUNT;a++) {
  247.             pos=readline(cbuf,pos,buf,size);
  248.             if (buf[0]) DoAssignDrive(cstuff,a,(char *)-1,buf);
  249.             if (pos==-1) goto endthis;
  250.         }
  251.     }
  252.     else {
  253.         for (a=0;a<ARCHIVECOUNT;a++) pos=readline(cbuf,pos,buf,size);
  254.     }
  255.  
  256.     bk=-1;
  257.     FOREVER {
  258.         if (pos>=size || pos==-1) break;
  259.         if (cbuf[pos]==5 && cbuf[pos+1]=='H') {
  260.             pos+=2;
  261.             if ((pos+sizeof(struct dopushotkey))>=size) break;
  262.             if ((hotkey=AllocMem(sizeof(struct dopushotkey),MEMF_CLEAR))) {
  263.                 CopyMem((char *)&cbuf[pos],(char *)hotkey,sizeof(struct dopushotkey));
  264.                 hotkey->func.function=NULL;
  265.                 hotkey->next=NULL;
  266.             }
  267.             pos+=sizeof(struct dopushotkey);
  268.             if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  269.             if (hotkey) {
  270.                 hotkey->func.function=getstringcopy(buf);
  271.                 if (curhotkey) curhotkey->next=hotkey;
  272.                 else cstuff->firsthotkey=hotkey;
  273.                 curhotkey=hotkey;
  274.             }
  275.         }
  276.         else if (cbuf[pos]==6 && cbuf[pos+1]=='F') {
  277.             pos+=2;
  278.             if ((pos+sizeof(struct wr_dopusfiletype))>=size) break;
  279.             if ((newtype=(struct dopusfiletype *)
  280.                 LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  281.                 CopyMem((char *)&cbuf[pos],(char *)newtype,sizeof(struct wr_dopusfiletype));
  282.                 if (config->version<=CONFIG_CHANGE_FTYPE) {
  283.                     newtype->type[31]=0;
  284.                     newtype->typeid[0]=0;
  285.                 }
  286.                 pos+=sizeof(struct wr_dopusfiletype);
  287.                 newtype->recognition=NULL;
  288.                 for (a=0;a<FILETYPE_FUNCNUM;a++) newtype->function[a]=NULL;
  289.                 if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  290.                 if ((newtype->recognition=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  291.                     strcpy(newtype->recognition,buf);
  292.                 for (a=0;a<FILETYPE_FUNCNUM;a++) {
  293.                     if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  294.                     if ((newtype->function[a]=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  295.                         strcpy(newtype->function[a],buf);
  296.                 }
  297.                 newtype->iconpath=NULL;
  298.                 if (config->version>CONFIG_CHANGE_FILETYPE) {
  299.                     pos=readline(cbuf,pos,buf,size);
  300.                     if (buf[0] && (newtype->iconpath=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  301.                         strcpy(newtype->iconpath,buf);
  302.                 }
  303.                 linkinnewfiletype(cstuff,newtype);
  304.             }
  305.         }
  306.         else if (cbuf[pos]==1 && cbuf[pos+1]=='F') {
  307.             pos+=2;
  308.             if ((pos+sizeof(struct olddopusfiletype))>=size) break;
  309.             if ((newtype=(struct dopusfiletype *)
  310.                 LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  311.                 CopyMem((char *)&cbuf[pos],(char *)&otype,sizeof(struct olddopusfiletype));
  312.                 pos+=sizeof(struct olddopusfiletype);
  313.                 LStrnCpy(newtype->type,otype.type,32);
  314.                 newtype->type[31]=0;
  315.                 newtype->typeid[0]=0;
  316.                 for (a=0;a<FILETYPE_FUNCNUM;a++) newtype->function[a]=NULL;
  317.                 for (a=0;a<4;a++) {
  318.                     strncpy(newtype->actionstring[a],otype.actionstring[a],39);
  319.                     newtype->actionstring[a][39]=0;
  320.                     newtype->which[a]=otype.which[a];
  321.                     newtype->stack[a]=otype.stack[a];
  322.                     newtype->pri[a]=otype.pri[a];
  323.                     newtype->delay[a]=otype.delay[a];
  324.                 }
  325.                 for (a=4;a<FILETYPE_FUNCNUM;a++) {
  326.                     newtype->stack[a]=4000;
  327.                     newtype->delay[a]=2;
  328.                 }
  329.                 for (a=0;a<4;a++) {
  330.                     if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  331.                     if ((newtype->function[a]=LAllocRemember(&cstuff->typekey,strlen(buf)+1,MEMF_CLEAR)))
  332.                         strcpy(newtype->function[a],buf);
  333.                 }
  334.                 buf[0]=0;
  335.                 if (otype.filepat[0])
  336.                     LSprintf(buf,"%lc%s%lc",FTYC_MATCHNAME,otype.filepat,
  337.                         ((otype.recogchars[0])?((otype.and)?FTYC_AND:FTYC_OR):FTYC_ENDSECTION));
  338.                 if (otype.recogchars[0]) {
  339.                     b=mv=0;
  340.                     for (a=0;a<100;a++) {
  341.                         if (!otype.recogchars[a] || otype.recogchars[a]==',') {
  342.                             buf2[b]=0;
  343.                             if (mv==0) {
  344.                                 if ((b=Atoh(buf2,0))>0) {
  345.                                     LSprintf(buf3,"%lc%ld%lc",FTYC_MOVETO,b,FTYC_ENDSECTION);
  346.                                     StrConcat(buf,buf3,4096);
  347.                                 }
  348.                                 mv=1;
  349.                             }
  350.                             else {
  351.                                 LSprintf(buf3,"%lc$%s%lc",FTYC_MATCH,buf2,FTYC_AND);
  352.                                 StrConcat(buf,buf3,4096);
  353.                                 mv=0;
  354.                             }
  355.                             if (!otype.recogchars[a]) break;
  356.                             b=0;
  357.                         }
  358.                         else {
  359.                             if (mv==1 && otype.recogchars[a]=='.') {
  360.                                 buf2[b++]='?'; buf2[b++]='?';
  361.                             }
  362.                             else buf2[b++]=otype.recogchars[a];
  363.                         }
  364.                     }
  365.                     b=strlen(buf);
  366.                     if (buf[b-1]==(char)FTYC_AND) buf[b-1]=0;
  367.                 }
  368.                 if ((newtype->recognition=LAllocRemember(&cstuff->typekey,strlen(buf)+1,MEMF_CLEAR)))
  369.                     strcpy(newtype->recognition,buf);
  370.                 linkinnewfiletype(cstuff,newtype);
  371.             }
  372.         }
  373.         else if ((cbuf[pos]==2 || cbuf[pos]==3) && cbuf[pos+1]=='G') {
  374.             if (cbuf[pos]==2) {
  375.                 a=0;
  376.                 b=sizeof(struct olddopusgadget)*GADCOUNT;
  377.             }
  378.             else {
  379.                 a=1;
  380.                 b=sizeof(struct newdopusfunction)*GADCOUNT;
  381.             }
  382.             pos+=2;
  383.             if ((pos+b)>=size) break;
  384.             ++bk;
  385.             if (!(temp=AllocMem(sizeof(struct dopusgadgetbanks),MEMF_CLEAR))) goto endthis;
  386.             if (!cstuff->firstbank) cstuff->firstbank=temp;
  387.             else bank->next=temp;
  388.             bank=temp;
  389.             if (a) {
  390.                 CopyMem((char *)&cbuf[pos],(char *)bank->gadgets,sizeof(struct newdopusfunction)*GADCOUNT);
  391.                 pos+=(sizeof(struct newdopusfunction)*GADCOUNT);
  392.             }
  393.             else {
  394.                 for (a=0;a<GADCOUNT;a++) {
  395.                     CopyMem((char *)&cbuf[pos],(char *)&bank->gadgets[a],10);
  396.                     CopyMem((char *)&cbuf[pos+10],(char *)&bank->gadgets[a].which,16);
  397.                     pos+=sizeof(struct olddopusgadget);
  398.                 }
  399.             }
  400.             for (gad=0;gad<GADCOUNT;gad++) {
  401.                 bank->gadgets[gad].function=NULL;
  402.                 buf[0]=0;
  403.                 if (pos>-1) {
  404.                     pos=readline(cbuf,pos,buf,size);
  405.                     DoAssignGadget(cstuff,bk,gad,(char *)-1,buf);
  406.                 }
  407.             }
  408.             if (config->version>CONFIG_NEW_FUNCTIONS) {
  409.                 for (gad=0;gad<GADCOUNT;gad++) {
  410.                     bank->gadgets[gad].name=NULL;
  411.                     buf[0]=0;
  412.                     if (pos>-1) {
  413.                         pos=readline(cbuf,pos,buf,size);
  414.                         DoAssignGadget(cstuff,bk,gad,buf,(char *)-1);
  415.                     }
  416.                 }
  417.             }
  418.             else {
  419.                 for (gad=0;gad<GADCOUNT;gad++) {
  420.                     strcpy(buf,(char *)&bank->gadgets[gad]);
  421.                     bank->gadgets[gad].name=getstringcopy(buf);
  422.                     bank->gadgets[gad].pad2[0]=0;
  423.                     bank->gadgets[gad].pad2[1]=0;
  424.                     bank->gadgets[gad].pad2[2]=0;
  425.                 }
  426.             }
  427.             if (pos==-1) break;
  428.         }
  429.     }
  430. endthis:
  431.     LFreeRemember(&key);
  432.     cstuff->curbank=cstuff->firstbank;
  433.     return(1);
  434. }
  435.  
  436. char *getstringcopy(str)
  437. char *str;
  438. {
  439.     char *newstr=NULL;
  440.  
  441.     if (str && (newstr=AllocMem(strlen(str)+1,0)))
  442.         strcpy(newstr,str);
  443.     return(newstr);
  444. }
  445.  
  446. __saveds DoSaveConfig(register char *name __asm("a0"),
  447.     register struct ConfigStuff *cstuff __asm("a1"))
  448. {
  449.     int a,out,ret=0;
  450.     struct dopusfiletype *type;
  451.     struct dopushotkey *hotkey;
  452.     struct dopusgadgetbanks *bank;
  453.     struct Config *config;
  454.  
  455.     if (!(config=cstuff->config)) return(0);
  456.  
  457.     config->version=CONFIG_VERSION;
  458.     config->magic=CONFIG_MAGIC;
  459.  
  460.     if (!(out=Open(name,MODE_NEWFILE))) return(FALSE);
  461.     if ((Write(out,(char *)config,sizeof(struct Config)))<sizeof(struct Config)) {
  462.         Close(out);
  463.         return(0);
  464.     }
  465.     for (a=0;a<MENUCOUNT;a++)
  466.         if (!writestring(out,config->menu[a].function)) goto error;
  467.     for (a=0;a<MENUCOUNT;a++)
  468.         if (!writestring(out,config->menu[a].name)) goto error;
  469.     for (a=0;a<DRIVECOUNT;a++)
  470.         if (!writestring(out,config->drive[a].function)) goto error;
  471.  
  472.     type=cstuff->firsttype;
  473.     while (type) {
  474.         if ((Write(out,"\006F",2))<2) goto error;
  475.         if ((Write(out,(char *)type,sizeof(struct wr_dopusfiletype)))<sizeof(struct wr_dopusfiletype))
  476.             goto error;
  477.         if (!writestring(out,type->recognition)) goto error;
  478.         for (a=0;a<FILETYPE_FUNCNUM;a++)
  479.             if (!writestring(out,type->function[a])) goto error;
  480.         if (!writestring(out,type->iconpath)) goto error;
  481.         type=type->next;
  482.     }
  483.     bank=cstuff->firstbank;
  484.     while (bank) {
  485.         if ((Write(out,"\003G",2))<2) goto error;
  486.         if ((Write(out,(char *)bank->gadgets,sizeof(struct dopusfunction)*GADCOUNT))<
  487.             sizeof(struct dopusfunction)*GADCOUNT) goto error;
  488.         for (a=0;a<GADCOUNT;a++)
  489.             if (!writestring(out,bank->gadgets[a].function)) goto error;
  490.         for (a=0;a<GADCOUNT;a++)
  491.             if (!writestring(out,bank->gadgets[a].name)) goto error;
  492.         bank=bank->next;
  493.     }
  494.     hotkey=cstuff->firsthotkey;
  495.     while (hotkey) {
  496.         if ((Write(out,"\005H",2))<2) goto error;
  497.         if ((Write(out,(char *)hotkey,sizeof(struct dopushotkey)))<sizeof(struct dopushotkey))
  498.             goto error;
  499.         if (!writestring(out,hotkey->func.function)) goto error;
  500.         hotkey=hotkey->next;
  501.     }
  502.     ret=1;
  503. error:
  504.     Close(out);
  505.     return(ret);
  506. }
  507.  
  508. writestring(file,string)
  509. int file;
  510. char *string;
  511. {
  512.     int b;
  513.     char nl=0;
  514.  
  515.     if (string) {
  516.         if ((Write(file,string,(b=(strlen(string)+1))))<b) return(0);
  517.     }
  518.     else Write(file,&nl,1);
  519.     return(1);
  520. }
  521.  
  522. struct DefaultGadFlag {
  523.     char code;
  524.     char qual;
  525.     char fpen;
  526.     char bpen;
  527. };
  528.  
  529. static ULONG defaultpalette[48]={
  530.     0xafffffff,0xafffffff,0xafffffff,
  531.     0x00000000,0x00000000,0x00000000,
  532.     0xffffffff,0xffffffff,0xffffffff,
  533.     0x0fffffff,0x5fffffff,0xbfffffff,
  534.     0xefffffff,0xafffffff,0x4fffffff,
  535.     0x7fffffff,0x00000000,0x7fffffff,
  536.     0xffffffff,0xffffffff,0x00000000,
  537.     0xcfffffff,0x2fffffff,0x00000000,
  538.     0xffffffff,0x8fffffff,0x00000000,
  539.     0xffffffff,0x00000000,0xffffffff,
  540.     0x9fffffff,0x6fffffff,0x3fffffff,
  541.     0x00000000,0xffffffff,0x9fffffff,
  542.     0x4fffffff,0xffffffff,0x3fffffff,
  543.     0x00000000,0x00000000,0x00000000,
  544.     0xffffffff,0xffffffff,0xffffffff,
  545.     0x2fffffff,0x5fffffff,0x9fffffff};
  546.  
  547. static char
  548.     *defgads[42]={
  549.         "All","Copy","Makedir","Hunt","Run","Comment","Read",
  550.         "None","Move","Assign","Search","","Datestamp","Hex Read",
  551.         "Parent","Rename","Check Fit","","","Protect","Show",
  552.         "Root","","GetSizes","","","Icon Info","Play",
  553.         "","","","","","Arc Ext","Edit",
  554.         "","DELETE","","","","Encrypt","Print"},
  555.     *revgads[35]={
  556.         "Toggle","Copy As","","","","","ANSI Read",
  557.         "","Move As","","","","","",
  558.         "","Clone","","","","","",
  559.         "","","ClearSizes","","","Add Icon","Loop Play",
  560.         "","","","","","","New File"},
  561.     *deffuncs[42]={
  562.         "*All","*Copy","*Makedir","*Hunt","*Run","*Comment","*Read",
  563.         "*None","*Move","*Assign","*Search","","*Datestamp","*HexRead",
  564.         "*Parent","*Rename","*CheckFit","","","*Protect","*Show",
  565.         "*Root","","*GetSizes","","","*IconInfo","*Play",
  566.         "","","","","","*User1","Ed {f}",
  567.         "","*DELETE","","","","*Encrypt","*Print"},
  568.     *revfuncs[35]={
  569.         "*Toggle","*CopyAs","","","","","*ANSIRead",
  570.         "","*MoveAs","","","","","",
  571.         "","*Clone","","","","","",
  572.         "","","*ClearSizes","","","*AddIcon","*LoopPlay",
  573.         "","","","","","","Ed {RsEnter filename to create new file:Untitled}"},
  574.  
  575.     *defmenus1[9]={
  576.         "Current dir~","Help!","Error help~",
  577.         "Configure~","About",
  578.         "Version~","Iconify","Button Iconify","Quit"},
  579.     *deffuncs1[9]={
  580.         "*CD","*Help","*ErrorHelp",
  581.         "*Configure","*About",
  582.         "*Version","*Iconify","*ButtonIconify","*Quit"},
  583.     *defmenus2[9]={
  584.         "Disk copy","Format","Install~","Relabel","Print dir","Disk info~",
  585.         "LHA add","Arc add","Zoo add"},
  586.     *deffuncs2[9]={
  587.         "*Diskcopy","*Format","*Install","*Relabel","*PrintDir","*DiskInfo",
  588.         "LHA -x a \"{d}{RsEnter LHA archive name}\" {O}",
  589.         "Arc a \"{d}{RsEnter Arc archive name}\" {O}",
  590.         "Zoo a \"{d}{RsEnter Zoo archive name}\" {O}"},
  591.  
  592.     *deftype_type[5]={
  593.         "LHA archive","ARC archive","ZOO archive","Icon","Default"},
  594.     *deftype_typeid[5]={
  595.         "LHA","ARC","ZOO","ICON","DEFAULT"},
  596.     *deftype_recog[6]={
  597.         "\002*.(lzh|lha)",
  598.         "\002*.arc",
  599.         "\002*.zoo",
  600.         "\001$E310\376\002*.info",
  601.         "\002*"},
  602.     *deftype_funcs[5][4]={
  603.         {"LHA v {f}","LHA -x -M x {f}","LHA v {f}","LHA -x -M x {f}"},
  604.         {"Arc v {f}","Arc x {f}","Arc v {f}","Arc x {f}"},
  605.         {"Zoo v {f}","Zoo x// {f}","Zoo v {f}","Zoo x// {f}"},
  606.         {"*IconInfo",NULL,NULL,NULL},
  607.         {"*SmartRead","*Copy",NULL,NULL}},
  608.     deftype_funcpos[5][4]={
  609.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  610.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  611.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  612.         {FTFUNC_DOUBLECLICK},
  613.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK}},
  614.     *deftype_action[5][4]={
  615.         {"Listing LHA archive...","Extracting files from LHA archive...",
  616.             "Listing LHA archive...","Extracting files from LHA archive..."},
  617.         {"Listing Arc archive...","Extracting files from Arc archive...",
  618.             "Listing Arc archive...","Extracting files from Arc archive..."},
  619.         {"Listing Zoo archive...","Extracting files from Zoo archive...",
  620.             "Listing Zoo archive...","Extracting files from Zoo archive..."},
  621.         {"Examining icon..."},
  622.         {"Reading file...","Copying file..."}},
  623.     deftype_delay[5][4]={
  624.         {0,2,0,2},
  625.         {0,2,0,2},
  626.         {-1,2,-1,2},
  627.         {2,2,2,2},
  628.         {2,2,2,2}};
  629.  
  630. unsigned char
  631.     defmenkeys1[10]={0,0x5f,0,0x33,0,0,0,0x17,0,0x10},
  632.     defmenqual1[10]={0,0,0,0x80,0,0,0,0x80,0,0x80},
  633.     defmenkeys2[9]={0x22,0x23,0x36,0,0,0,0,0,0},
  634.     defmenqual2[9]={0x80,0x80,0x80,0,0,0,0,0,0};
  635.  
  636. static struct DefaultGadFlag
  637.     default_gadflags[]={
  638.         {0x20,IEQUALIFIER_CONTROL,6,3},
  639.         {0x33,IEQUALIFIER_CONTROL,6,5},
  640.         {0x37,IEQUALIFIER_CONTROL,5,4},
  641.         {0x25,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,4,1},
  642.         {0x16,IEQUALIFIER_CONTROL,1,4},
  643.         {0x33,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,5,0},
  644.         {0x13,IEQUALIFIER_CONTROL,6,7},
  645.  
  646.         {0x36,IEQUALIFIER_CONTROL,6,3},
  647.         {0x37,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,5},
  648.         {0,0,5,4},
  649.         {0x21,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,4,1},
  650.         {0,0,1,0},
  651.         {0x22,IEQUALIFIER_CONTROL,5,0},
  652.         {0x25,IEQUALIFIER_CONTROL,6,7},
  653.  
  654.         {0x19,IEQUALIFIER_CONTROL,6,3},
  655.         {0x13,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,5},
  656.         {0x23,IEQUALIFIER_CONTROL,5,4},
  657.         {0,0,1,0},
  658.         {0,0,1,0},
  659.         {0x14,IEQUALIFIER_CONTROL,5,0},
  660.         {0x21,IEQUALIFIER_CONTROL,6,7},
  661.  
  662.         {0x18,IEQUALIFIER_CONTROL,6,3},
  663.         {0,0,1,0},
  664.         {0x24,IEQUALIFIER_CONTROL,5,4},
  665.         {0,0,1,0},
  666.         {0,0,1,0},
  667.         {0x17,IEQUALIFIER_CONTROL,5,0},
  668.         {0x15,IEQUALIFIER_CONTROL,6,7},
  669.  
  670.         {0,0,1,0},
  671.         {0,0,1,0},
  672.         {0,0,1,0},
  673.         {0,0,1,0},
  674.         {0,0,1,0},
  675.         {0x12,IEQUALIFIER_CONTROL,5,0},
  676.         {0x12,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,7},
  677.  
  678.         {0,0,1,0},
  679.         {0x22,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,2,7},
  680.         {0,0,1,0},
  681.         {0,0,1,0},
  682.         {0,0,1,0},
  683.         {0,0,5,0},
  684.         {0x19,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,7}};
  685.  
  686. static short
  687.     deftype_which[5][4]={
  688.         {FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  689.             FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  690.         {FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  691.             FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  692.         {FLAG_DOALL|FLAG_OUTWIND,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  693.             FLAG_DOALL|FLAG_OUTWIND,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  694.         {0,0,0,0},
  695.         {0,0,0,0}};
  696.  
  697. __saveds DoDefaultConfig(register struct ConfigStuff *cstuff __asm("a0"))
  698. {
  699.     int a,b,h,i;
  700.     struct Config *config;
  701.     struct dopusgadgetbanks *firstbank;
  702.     struct dopusfiletype *type;
  703.     char name[256];
  704.  
  705.     if (!(config=cstuff->config)) return(0);
  706.     DoFreeConfig(cstuff);
  707.  
  708.     if ((DoFindSystemFile("DirectoryOpus.DefCFG",name,256,SYSFILE_DATA)) &&
  709.         (DoReadConfig(name,cstuff))==1) return(1);
  710.  
  711.     /* Operation */
  712.  
  713.     config->copyflags=COPY_DATE|COPY_PROT|COPY_NOTE;
  714.     config->dateformat=DATE_DOS|DATE_SUBST|DATE_12HOUR;
  715.     config->existflags=REPLACE_ASK;
  716.     config->deleteflags=DELETE_ASK;
  717.     config->errorflags=ERROR_ENABLE_DOS|ERROR_ENABLE_OPUS;
  718.     config->generalflags=GENERAL_DRAG|GENERAL_DOUBLECLICK|GENERAL_ACTIVATE;
  719.     config->iconflags=ICONFLAG_MAKEDIRICON|ICONFLAG_DOUNTOICONS;
  720.  
  721.     for (h=0;h<2;h++) {
  722.         for (i=0;i<5;i++) config->displaypos[h][i]=i;
  723.         for (i=5;i<16;i++) config->displaypos[h][i]=-1;
  724.         config->displaylength[h][0]=28;
  725.         config->displaylength[h][1]=80;
  726.         config->displaylength[h][2]=40;
  727.         config->displaylength[h][3]=32;
  728.         config->displaylength[h][4]=32;
  729.         config->sortmethod[h]=0;
  730.         config->separatemethod[h]=1;
  731.     }
  732.     config->sortflags=0;
  733.     config->formatflags=0;
  734.  
  735.     config->dynamicflags=UPDATE_FREE|UPDATE_SCROLL|UPDATE_LEFTJUSTIFY|UPDATE_PROGRESSINDICATOR|UPDATE_REDRAW;
  736.  
  737.     /* System */
  738.  
  739.     strcpy(config->outputcmd,"NewCLI");
  740.     strcpy(config->output,"CON:20/10/600/180/Directory Opus Output");
  741.     strcpy(config->shellstartup,"Shell-Startup");
  742.     config->priority=0;
  743.  
  744.     config->icontype=ICON_MEMORY|ICON_DATE|ICON_TIME;
  745.     config->scrclktype=SCRCLOCK_MEMORY|SCRCLOCK_DATE|SCRCLOCK_TIME;
  746.  
  747.     config->bufcount=10;
  748.     config->dirflags=DIRFLAGS_FINDEMPTY|DIRFLAGS_REREADOLD|
  749.                                         DIRFLAGS_SMARTPARENT|DIRFLAGS_CHECKBUFS|
  750.                                         DIRFLAGS_AUTODISKC|DIRFLAGS_AUTODISKL;
  751.     config->showfree=SHOWFREE_KILO;
  752.  
  753.     config->hotkeycode=(USHORT)~0;
  754.     config->hotkeyqual=IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT;
  755.     config->hotkeyflags=0;
  756.  
  757.     config->toolicon[0]=0;
  758.     config->projecticon[0]=0;
  759.     config->drawericon[0]=0;
  760.     config->defaulttool[0]=0;
  761.     config->addiconflags=0;
  762.  
  763.     config->loadexternal=0;
  764.     config->language[0]=0;
  765.  
  766.     config->hiddenbit=0;
  767.     config->showpat[0]=0;
  768.     config->hidepat[0]=0;
  769.     config->showpatparsed[0]=0;
  770.     config->hidepatparsed[0]=0;
  771.  
  772.     config->autodirs[0][0]=0;
  773.     config->autodirs[1][0]=0;
  774.     config->startupscript[0]=0;
  775.     config->uniconscript[0]=0;
  776.     config->configreturnscript[0]=0;
  777.  
  778.     config->viewbits=VIEWBITS_SHOWBLACK|VIEWBITS_TEXTBORDERS;
  779.     config->showdelay=0;
  780.     config->fadetime=2;
  781.     config->tabsize=8;
  782.  
  783.     /* Screen */
  784.  
  785.     for (a=0;a<3;a++) {
  786.         config->arrowpos[a]=2;
  787.         config->arrowsize[a]=8;
  788.     }
  789.     config->sliderwidth=10;
  790.     config->sliderheight=7;
  791.     config->stringheight=8;
  792.  
  793.     config->statusfg=1; config->statusbg=0;
  794.     config->disknameselfg=2; config->disknameselbg=7;
  795.     config->disknamefg=1; config->disknamebg=0;
  796.     config->dirsselfg=2; config->dirsselbg=3;
  797.     config->dirsfg=3; config->dirsbg=0;
  798.     config->filesselfg=2; config->filesselbg=1;
  799.     config->filesfg=1; config->filesbg=0;
  800.     config->slidercol=1; config->sliderbgcol=0;
  801.     config->arrowfg=1; config->arrowbg=0;
  802.     config->littlegadfg=1; config->littlegadbg=0;
  803.     config->clockfg=1; config->clockbg=0;
  804.     config->requestfg=1; config->requestbg=0;
  805.     config->gadgettopcol=2; config->gadgetbotcol=1;
  806.     config->stringfgcol=1; config->stringbgcol=0;
  807.     config->stringselfgcol=1; config->stringselbgcol=4;
  808.  
  809.     for (i=0;i<NUMFONTS;i++) {
  810.         config->fontsizes[i]=8;
  811.         strcpy(config->fontbufs[i],"topaz");
  812.     }
  813.  
  814.     config->generalscreenflags=SCR_GENERAL_TINYGADS|
  815.                                                             SCR_GENERAL_INDICATERMB|
  816.                                                             SCR_GENERAL_REQDRAG|
  817.                                                             SCR_GENERAL_NEWLOOKMENU|
  818.                                                             SCR_GENERAL_WINBORDERS;
  819.  
  820.     CopyMem((char *)defaultpalette,(char *)config->new_palette,sizeof(defaultpalette));
  821.  
  822.     config->screenmode=MODE_WORKBENCHCLONE;
  823.     config->scrdepth=3;
  824.     config->scrw=-1;
  825.     config->scrh=-1;
  826.     config->screenflags=0;
  827.  
  828.     config->scr_winx=0;
  829.     config->scr_winx=0;
  830.     config->scr_winw=-1;
  831.     config->scr_winh=-1;
  832.  
  833.     /* Misc Stuff */
  834.  
  835.     config->gadgetrows=6;
  836.  
  837.     config->iconx=252; config->icony=0;
  838.     config->wbwinx=0; config->wbwiny=0;
  839.     config->iconbutx=100; config->iconbuty=40;
  840.     config->config_x=-1; config->config_y=-1;
  841.  
  842.     for (a=0;a<2;a++) {
  843.         config->scrollborders[a].MinX=~0;
  844.         config->scrollborders[a].MaxX=~0;
  845.         config->scrollborders[a].MinY=~0;
  846.         config->scrollborders[a].MaxY=~0;
  847.     }
  848.  
  849.     config->windowdelta=0;
  850.     config->slider_pos=1;
  851.  
  852.     /* Buttons */
  853.  
  854.     for (i=0;i<42;i++) DoAssignGadget(cstuff,0,i,defgads[i],deffuncs[i]);
  855.     for (i=0;i<35;i++) DoAssignGadget(cstuff,0,i+42,revgads[i],revfuncs[i]);
  856.     for (i=78;i<GADCOUNT;i++) DoAssignGadget(cstuff,0,i,NULL,NULL);
  857.  
  858.     if (firstbank=cstuff->firstbank) {
  859.         for (i=0;i<GADCOUNT;i++) {
  860.             firstbank->gadgets[i].which=0;
  861.             firstbank->gadgets[i].type=0;
  862.             firstbank->gadgets[i].stack=4000;
  863.             firstbank->gadgets[i].pri=0;
  864.             firstbank->gadgets[i].delay=2;
  865.             if (i<42) {
  866.                 firstbank->gadgets[i].key=default_gadflags[i].code;
  867.                 firstbank->gadgets[i].qual=default_gadflags[i].qual;
  868.                 firstbank->gadgets[i].fpen=default_gadflags[i].fpen;
  869.                 firstbank->gadgets[i].bpen=default_gadflags[i].bpen;
  870.             }
  871.             else {
  872.                 firstbank->gadgets[i].fpen=1;
  873.                 firstbank->gadgets[i].bpen=0;
  874.                 if (i==57) {
  875.                     firstbank->gadgets[i].key=0x28;
  876.                     firstbank->gadgets[i].qual=IEQUALIFIER_CONTROL;
  877.                 }
  878.                 else if (i==68) {
  879.                     firstbank->gadgets[i].key=0x17;
  880.                     firstbank->gadgets[i].qual=IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT;
  881.                 }
  882.                 else {
  883.                     firstbank->gadgets[i].key=0;
  884.                     firstbank->gadgets[i].qual=0;
  885.                 }
  886.             }
  887.         }
  888.         firstbank->gadgets[34].which=FLAG_ASYNC|FLAG_CDSOURCE;
  889.         firstbank->gadgets[76].which=FLAG_ASYNC|FLAG_CDSOURCE;
  890.     }
  891.     cstuff->curbank=firstbank;
  892.  
  893.     /* Menus */
  894.  
  895.     strcpy(config->menutit[0],"Project");
  896.     strcpy(config->menutit[1],"Function");
  897.     for (i=2;i<5;i++) config->menutit[i][0]=0;
  898.  
  899.     for (i=0;i<9;i++) {
  900.         DoAssignMenu(cstuff,i,defmenus1[i],deffuncs1[i]);
  901.         config->menu[i].key=defmenkeys1[i];
  902.         config->menu[i].qual=defmenqual1[i];
  903.     }
  904.     for (i=20;i<29;i++) {
  905.         h=i-20;
  906.         DoAssignMenu(cstuff,i,defmenus2[h],deffuncs2[h]);
  907.         config->menu[i].key=defmenkeys2[h];
  908.         config->menu[i].qual=defmenqual2[h];
  909.     }
  910.     for (i=26;i<29;i++) {
  911.         config->menu[i].which=FLAG_OUTWIND|FLAG_CDSOURCE|FLAG_DOALL|FLAG_SCANDEST|((i==27)?0:FLAG_RECURSE);
  912.         config->menu[i].delay=-1;
  913.     }
  914.  
  915.     /* Drives */
  916.  
  917.     DoGetDevices(cstuff);
  918.  
  919.     for (i=0;i<DRIVECOUNT;i++) {
  920.         config->drive[i].key=0;
  921.         config->drive[i].qual=0;
  922.         config->drive[i].fpen=1;
  923.         config->drive[i].bpen=0;
  924.     }
  925.  
  926.     /* Filetypes */
  927.  
  928.     for (i=0;i<5;i++) {
  929.         if ((type=(struct dopusfiletype *)
  930.             LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  931.             strcpy(type->type,deftype_type[i]);
  932.             strcpy(type->typeid,deftype_typeid[i]);
  933.             if (type->recognition=LAllocRemember(&cstuff->typekey,strlen(deftype_recog[i])+1,0))
  934.                 strcpy(type->recognition,deftype_recog[i]);
  935.             for (a=0;a<4;a++) {
  936.                 if (deftype_funcs[i][a]) {
  937.                     b=deftype_funcpos[i][a];
  938.                     strcpy(type->actionstring[b],deftype_action[i][a]);
  939.                     type->which[b]=deftype_which[i][a];
  940.                     type->delay[b]=deftype_delay[i][a];
  941.                     type->stack[b]=4000;
  942.                     if (type->function[b]=LAllocRemember(&cstuff->typekey,strlen(deftype_funcs[i][a])+1,0))
  943.                     strcpy(type->function[b],deftype_funcs[i][a]);
  944.                 }
  945.             }
  946.             linkinnewfiletype(cstuff,type);
  947.         }
  948.     }
  949.     return(1);
  950. }
  951.  
  952. readline(buf,pos,buf1,size)
  953. char *buf;
  954. int pos;
  955. char *buf1;
  956. int size;
  957. {
  958.     int a;
  959.  
  960.     for (a=0;a<4096;a++) {
  961.         if (size==pos || buf[pos]==0) {
  962.             buf1[a]=0;
  963.             if (size==pos) return(-1);
  964.             return(pos+1);
  965.         }
  966.         buf1[a]=buf[pos];
  967.         ++pos;
  968.     }
  969.     buf1[pos]=0;
  970.     return(pos);
  971. }
  972.  
  973. __saveds DoGetDevices(register struct ConfigStuff *cstuff __asm("a0"))
  974. {
  975.     struct DeviceList *devlist;
  976.     struct RootNode *rootnode;
  977.     struct DosInfo *dosinfo;
  978.     struct Config *config;
  979.     char devname[16],pathname[256];
  980.     int gap,i,j,k,a,p,l,d;
  981.  
  982.     if (!(config=cstuff->config)) return(0);
  983.     rootnode=(struct RootNode *) DOSBase->dl_Root;
  984.     dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
  985.     devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  986.     a=0;
  987.     while (devlist) {
  988.         if (devlist->dl_Type==DLT_DEVICE && devlist->dl_Task) {
  989.             BtoCStr((BPTR)devlist->dl_Name,pathname,256);
  990.             LStrCat(pathname,":");
  991.             strncpy(devname,pathname,15); devname[15]=0;
  992.             DoAssignDrive(cstuff,a,devname,pathname);
  993.             ++a;
  994.             if (a==DRIVECOUNT) break;
  995.         }
  996.         devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  997.     }
  998.     for (gap=a/2;gap>0;gap/=2) {
  999.         for (i=gap;i<a;i++) {
  1000.             for (j=i-gap;j>=0;j-=gap) {
  1001.                 k=j+gap;
  1002.                 if (LStrCmpI(config->drive[j].name,config->drive[k].name)<=0) break;
  1003.                 SwapMem((char *)&config->drive[j],(char *)&config->drive[k],sizeof(struct dopusfunction));
  1004.             }
  1005.         }
  1006.     }
  1007.     d=a;
  1008.     if (a<DRIVECOUNT) {
  1009.         devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  1010.         while (devlist) {
  1011.             if (devlist->dl_Type==DLT_DIRECTORY) {
  1012.                 BtoCStr((BPTR)devlist->dl_Name,pathname,256);
  1013.                 LStrCat(pathname,":");
  1014.                 strncpy(devname,pathname,15); devname[15]=0;
  1015.                 DoAssignDrive(cstuff,a,devname,pathname);
  1016.                 ++a;
  1017.                 if (a==DRIVECOUNT) break;
  1018.             }
  1019.             devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  1020.         }
  1021.     }
  1022.     p=a-d;
  1023.     for (gap=p/2;gap>0;gap/=2) {
  1024.         for (i=gap;i<p;i++) {
  1025.             for (j=i-gap;j>=0;j-=gap) {
  1026.                 k=j+gap+d; l=j+d;
  1027.                 if (LStrCmpI(config->drive[l].name,config->drive[k].name)<=0) break;
  1028.                 SwapMem((char *)&config->drive[l],(char *)&config->drive[k],sizeof(struct dopusfunction));
  1029.             }
  1030.         }
  1031.     }
  1032.     if (a<DRIVECOUNT) {
  1033.         for (i=a;i<DRIVECOUNT;i++) DoAssignDrive(cstuff,i,NULL,NULL);
  1034.     }
  1035. }
  1036.  
  1037. void __saveds DoAssignGadget(register struct ConfigStuff *cstuff __asm("a0"),
  1038.     register int bk __asm("d0"),
  1039.     register int gad __asm("d1"),
  1040.     register char *name __asm("a1"),
  1041.     register char *func __asm("a2"))
  1042. {
  1043.     struct dopusgadgetbanks *bank,*temp;
  1044.     int a;
  1045.  
  1046.     bank=cstuff->firstbank;
  1047.     for (a=0;a<bk;a++) {
  1048.         if (!bank || !bank->next) break;
  1049.         bank=bank->next;
  1050.     }
  1051.     if (a<bk || !bank) {
  1052.         if (!(temp=AllocMem(sizeof(struct dopusgadgetbanks),MEMF_CLEAR))) return;
  1053.         if (bank) bank->next=temp;
  1054.         else cstuff->firstbank=temp;
  1055.         bank=temp;
  1056.     }
  1057.  
  1058.     if (name!=(char *)-1) {
  1059.         freestring(bank->gadgets[gad].name);
  1060.         bank->gadgets[gad].name=NULL;
  1061.         if (name && name[0]) bank->gadgets[gad].name=getstringcopy(name);
  1062.     }
  1063.     if (func!=(char *)-1) {
  1064.         freestring(bank->gadgets[gad].function);
  1065.         bank->gadgets[gad].function=NULL;
  1066.         if (func && func[0]) bank->gadgets[gad].function=getstringcopy(func);
  1067.     }
  1068. }
  1069.  
  1070. void __saveds DoAssignMenu(register struct ConfigStuff *cstuff __asm("a0"),
  1071.     register int men __asm("d0"),
  1072.     register char *name __asm("a1"),
  1073.     register char *func __asm("a2"))
  1074. {
  1075.     struct Config *config;
  1076.  
  1077.     if (!(config=cstuff->config)) return;
  1078.     if (name!=(char *)-1) {
  1079.         freestring(config->menu[men].name);
  1080.         config->menu[men].name=NULL;
  1081.         if (name && name[0]) config->menu[men].name=getstringcopy(name);
  1082.     }
  1083.     if (func!=(char *)-1) {
  1084.         freestring(config->menu[men].function);
  1085.         config->menu[men].function=NULL;
  1086.         if (func && func[0]) config->menu[men].function=getstringcopy(func);
  1087.     }
  1088. }
  1089.  
  1090. void DoAssignDrive(cstuff,drv,name,path)
  1091. struct ConfigStuff *cstuff;
  1092. int drv;
  1093. char *name,*path;
  1094. {
  1095.     struct Config *config;
  1096.  
  1097.     if (!(config=cstuff->config)) return;
  1098.     if (name!=(char *)-1) {
  1099.         if (!name) config->drive[drv].name[0]=0;
  1100.         else strcpy(config->drive[drv].name,name);
  1101.     }
  1102.     if (path!=(char *)-1) {
  1103.         freestring(config->drive[drv].function);
  1104.         config->drive[drv].function=NULL;
  1105.         if (path && path[0]) config->drive[drv].function=getstringcopy(path);
  1106.     }
  1107. }
  1108.  
  1109. void linkinnewfiletype(cstuff,temp)
  1110. struct ConfigStuff *cstuff;
  1111. struct dopusfiletype *temp;
  1112. {
  1113.     struct dopusfiletype *pos;
  1114.  
  1115.     temp->next=NULL;
  1116.     if (!(pos=cstuff->firsttype)) cstuff->firsttype=temp;
  1117.     else {
  1118.         while (pos->next) {
  1119.             if (strcmp(pos->next->type,"Default")==0) {
  1120.                 temp->next=pos->next;
  1121.                 break;
  1122.             }
  1123.             pos=pos->next;
  1124.         }
  1125.         pos->next=temp;
  1126.     }
  1127. }
  1128.  
  1129. void __saveds DoFreeConfig(register struct ConfigStuff *cstuff __asm("a0"))
  1130. {
  1131.     int a;
  1132.     struct Config *config;
  1133.     struct dopusgadgetbanks *bank,*temp;
  1134.     struct dopushotkey *hotkey,*temphot;
  1135.  
  1136.     if (!(config=cstuff->config)) return;
  1137.  
  1138.     for (a=0;a<MENUCOUNT;a++) {
  1139.         DoAssignMenu(cstuff,a,NULL,NULL);
  1140.         config->menu[a].which=0; config->menu[a].type=0;
  1141.         config->menu[a].stack=4000; config->menu[a].pri=0;
  1142.         config->menu[a].delay=2;
  1143.         config->menu[a].fpen=0; config->menu[a].bpen=1;
  1144.         config->menu[a].key=0; config->menu[a].qual=0;
  1145.     }
  1146.     for (a=0;a<DRIVECOUNT;a++) {
  1147.         DoAssignDrive(cstuff,a,NULL,NULL);
  1148.         config->drive[a].key=config->drive[a].qual=0;
  1149.         config->drive[a].fpen=3; config->drive[a].bpen=0;
  1150.     }
  1151.  
  1152.     bank=cstuff->firstbank;
  1153.     while (bank) {
  1154.         for (a=0;a<GADCOUNT;a++) {
  1155.             freestring(bank->gadgets[a].name);
  1156.             freestring(bank->gadgets[a].function);
  1157.         }
  1158.         temp=bank->next;
  1159.         FreeMem(bank,sizeof(struct dopusgadgetbanks));
  1160.         bank=temp;
  1161.     }
  1162.     cstuff->firstbank=cstuff->curbank=NULL;
  1163.  
  1164.     hotkey=cstuff->firsthotkey;
  1165.     while (hotkey) {
  1166.         temphot=hotkey->next;
  1167.         freestring(hotkey->func.function);
  1168.         FreeMem(hotkey,sizeof(struct dopushotkey));
  1169.         hotkey=temphot;
  1170.     }
  1171.     cstuff->firsthotkey=NULL;
  1172.  
  1173.     LFreeRemember(&cstuff->typekey);
  1174.     cstuff->firsttype=NULL;
  1175. }
  1176.  
  1177. void freestring(str)
  1178. char *str;
  1179. {
  1180.     if (str) FreeMem(str,strlen(str)+1);
  1181. }
  1182.  
  1183. __saveds DoCheckConfig(register struct ConfigStuff *cstuff __asm("a0"))
  1184. {
  1185.     struct Config *config;
  1186.  
  1187.     if (!(config=cstuff->config)) return(0);
  1188.  
  1189.     if (config->sliderheight<5) config->sliderheight=5;
  1190.     else if (config->sliderheight>49) config->sliderheight=49;
  1191.     if (config->sliderwidth<8) config->sliderwidth=8;
  1192.     else if (config->sliderwidth>108) config->sliderwidth=108;
  1193. }
  1194.  
  1195. char *look_dirs[]={
  1196.     "C:","DOpus:C/",
  1197.     "S:","DOpus:S/",
  1198.     "LIBS:","DOpus:Libs/",
  1199.     "REXX:","DOpus:Rexx/",
  1200.     "C:","DOpus:Modules/",
  1201.     "S:","DOpus:Requesters/"};
  1202.  
  1203. __saveds DoFindSystemFile(register char *name __asm("a0"),
  1204.     register char *buf __asm("a1"),
  1205.     register int size __asm("d0"),
  1206.     register int type __asm("d1"))
  1207. {
  1208.     char temp[256];
  1209.  
  1210. tryloop:
  1211.     LStrnCpy(temp,name,256);
  1212.     if (DOSBase->dl_lib.lib_Version<36 ||
  1213.         !(FindSegment(temp,NULL,0))) {
  1214.         if (DoCheckExist(temp,NULL)>=0) {
  1215.             int a;
  1216.  
  1217.             for (a=0;a<2;a++) {
  1218.                 StrCombine(temp,look_dirs[(type*2)+a],name,256);
  1219.                 if (DoCheckExist(temp,NULL)<0) break;
  1220.             }
  1221.             if (a==2) temp[0]=0;
  1222.         }
  1223.         else {
  1224.             BPTR lock;
  1225.  
  1226.             if (lock=Lock("",ACCESS_READ)) {
  1227.                 DoPathName(lock,temp,256);
  1228.                 UnLock(lock);
  1229.                 DoTackOn(temp,name,256);
  1230.             }
  1231.         }
  1232.     }
  1233.     if (temp[0]) {
  1234.         LStrnCpy(buf,temp,size);
  1235.         return(1);
  1236.     }
  1237.     else if (type==SYSFILE_MODULE) {
  1238.         struct DOpusSimpleRequest req;
  1239.         char reqbuf[300];
  1240.         static char *req_gads[3]={"Try Again","Cancel",NULL};
  1241.         static int req_rets[2]={1,0};
  1242.  
  1243.         LSprintf(reqbuf,"Unable to find the file \"%s\"\nin either the C: directory or the\n\
  1244. DOPUS:Modules/ directory. Insert DOpus disk\nif necessary and select Try Again, or\n\
  1245. Cancel to abort the operation",name);
  1246.  
  1247.         req.text=reqbuf;
  1248.         req.gads=req_gads;
  1249.         req.rets=req_rets;
  1250.         req.hi=-1; req.lo=-1;
  1251.         req.fg=-1; req.bg=-1;
  1252.         req.strbuf=NULL;
  1253.         req.flags=0;
  1254.         req.font=NULL;
  1255.         if (DoSimpleRequest(NULL,&req)) goto tryloop;
  1256.     }
  1257.     LStrnCpy(buf,name,size);
  1258.     return(0);
  1259. }
  1260.